package com.yang.mall.config;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.api.R;
import com.yang.mall.tools.JWTUtils;
import com.yang.mall.tools.MAPIHttpServletRequestWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Async;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

/**
 * 中台前端TOKEN安全身份校验
 *
 * @Author: duke
 * @Date: 2019/1/4 10:48 AM
 */
@WebFilter(filterName = "AuthTokenFilter", urlPatterns = {
        "/admin/*",
        "/h5/*",
})
public class AuthTokenFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class);

    private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(
            Arrays.asList(
                    "/admin/user/login",
                    "/admin/uploadFile",
                    "/h5/member/login",
                    "/h5/member/register",
                    "/h5/productSort/querySort",
                    "/h5/banner/getList",
                    "/h5/product/list",
                    "/h5/productSort/pullSort",
                    "/h5/product/queryList",
                    "/h5/product/detail",
                    "/h5/order/list"
            )));

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain) throws IOException,
            ServletException {


        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse rep = (HttpServletResponse) response;
        // 允许访问的源
        String headerOrigin = req.getHeader("Origin");
        if (StringUtils.isNotEmpty(headerOrigin)) {
            rep.setHeader("Access-Control-Allow-Origin", headerOrigin);
        }
        rep.setHeader("Access-Control-Allow-Origin", "*");  // 允许跨域的地址为所有
        rep.setHeader("Content-type", "application/json");
        rep.setHeader("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With,X-App-Id, X-Token");
        rep.addHeader("Access-Control-Max-Age", "3600");  // 非简单请求，只要第一次通过OPTIONS检查 在1小时之内不会在调用OPTIONS进行检测
        rep.setHeader("Access-Control-Allow-Credentials", "true");  // 带有Cookie的跨域请求，此值必须设置为true。
        rep.setHeader("Access-Control-ALLow-Methods","*");
        rep.setHeader("Access-Control-ALlow-Headers","authorization,content-type,Cookie");
        rep.setHeader("Access-Control-Expose-Headers","X-forwared-port,X-forwarded-host");
        rep.setHeader("Access-Control-expose-Headers","Authorization,BiToken,Cookie");
        rep.setHeader("Set-Cookie","Samesite=None");

        String token = req.getHeader("token");
        String path = req.getRequestURI().substring(req.getContextPath().length()).replaceAll("[/]+$", "");
        String memberId = req.getParameter("memberId");
        if ("OPTIONS".equals(req.getMethod())) {
            rep.setStatus(HttpServletResponse.SC_OK);
            return;
        }
        logger.info("memberId:"+memberId);
        logger.info("token:"+token);
        logger.info("path:"+path);
        //不检查安全名单
        if (ALLOWED_PATHS.contains(path)) {
            logger.info("不检查安全名单");
            chain.doFilter(request, rep);
            return;
        }

        logger.info("req.getMethod():"+req.getMethod());
        //if (req.getMethod().equals("OPTIONS")) {
        //    logger.info("OPTIONS");
        //    rep.setStatus(200);
        //    chain.doFilter(request, rep);
        //    return;
        //}

        //没有TOKEN非法请求
        //if (StringUtils.isEmpty(memberId)) {
        //    print(rep, stateString(601, "对不起，此请求非正常请求"));
        //    return;
        //}

        ////验证JWT的签名，返回CheckResult对象
        //boolean checkToken = JWTUtils.checkToken(token, memberId);
        //if(!checkToken){
        //    print(rep, stateString(401, "令牌不合法～"));
        //}

        // clone body参数
        ServletRequest requestWrapper = new MAPIHttpServletRequestWrapper(req);
        String body = MAPIHttpServletRequestWrapper.getBodyString(requestWrapper);


        chain.doFilter(requestWrapper, response);
    }

    @Override
    public void destroy() {
    }

    public void print(HttpServletResponse response, Object message) {
        try {
            response.setStatus(HttpStatus.OK.value());
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            response.setHeader("Content-type", "application/json");
            response.setHeader("Access-Control-Allow-Origin", "*"); //解决跨域访问报错
            response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
            response.setHeader("Access-Control-Max-Age", "3600"); //设置过期时间
            response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization");
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // 支持HTTP 1.1.
            response.setHeader("Pragma", "no-cache"); // 支持HTTP 1.0. response.setHeader("Expires", "0");
            PrintWriter writer = response.getWriter();
            writer.write(message.toString());
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private String stateString(int code, String msg) {
        String template = "{\"code\":\"%s\",\"msg\":\"%s\"}";
        return String.format(template, code, msg);
    }


}
